package demo.android.com.mvpdemo.mvp3.proxy;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import demo.android.com.mvpdemo.mvp3.base.BasePresenter;
import demo.android.com.mvpdemo.mvp3.base.BaseView;
import demo.android.com.mvpdemo.mvp3.inject.InjectPresenter;

/**
 * Created by Vya on 2018/1/10 0010.
 */

public class MvpProxyImpl<V extends BaseView> implements IMvpProxy {
    private List<BasePresenter> mPresenters;
    private V mView;
    public MvpProxyImpl(V view){
        //判断是否为空，是否是一个接口
        if(null == view){
            throw new RuntimeException("view is null in MvpProxyImpl constructor");
        }
        this.mView = view;
        mPresenters = new ArrayList<>();
    }

    @Override
    public void bindAndCreatePresenter() {
        Field[] fields = mView.getClass().getDeclaredFields();
        for(Field field : fields){
            InjectPresenter injectPresenter = field.getAnnotation(InjectPresenter.class);
            if(injectPresenter != null){
                Class<? extends BasePresenter> presenterClazz = null;

                presenterClazz = (Class<? extends BasePresenter>) field.getType();  //强转不报错，是因为泛型擦除的原因
                if(!BasePresenter.class.isAssignableFrom(presenterClazz)){
                    throw new RuntimeException("No support inject type "+presenterClazz.getName());
                }


                try {
                    BasePresenter basePresenter = presenterClazz.newInstance();

                    checkView(basePresenter);

                    basePresenter.attach(mView);

                    //设置
                    field.setAccessible(true);
                    field.set(mView,basePresenter);
                    mPresenters.add(basePresenter);
                } catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 检测 View层是否实现了接口，View
     * @param basePresenter
     */
    private void checkView(BasePresenter basePresenter) {
        //获取 Presenter 上面的View
        Type[] params = ((ParameterizedType)basePresenter.getClass().getGenericSuperclass()).getActualTypeArguments();
        Class<?> viewClass = null;
        try{
            //最好要判断一下类型
            viewClass = (Class)params[0];
            Class<?>[] clazzs = mView.getClass().getInterfaces();
            //是否实现了
            boolean isImplements = false;
            for(Class<?> clazz : clazzs){
                if(clazz.isAssignableFrom(viewClass)){
                    isImplements = true;
                }
            }
            // 没实现抛异常
            if(!isImplements){
                throw  new RuntimeException(mView.getClass().getSimpleName() + "not implements " + viewClass.getCanonicalName());
            }

        }catch(Exception e){
            throw  new RuntimeException(mView.getClass().getSimpleName() + "not implements " + viewClass.getCanonicalName());
        }

    }

    @Override
    public void unbindPresenter() {
        // 一定要解绑
        for (BasePresenter presenter : mPresenters) {
            presenter.detach();
        }
        mView = null;
    }
}
